Skip to content

feat(v1): make FetchBlock and ReadData single-item operations - #208

Open
carbolymer wants to merge 1 commit into
utxorpc:feat/initialize-v1-versionfrom
carbolymer:sync-fetchblock-single-block
Open

feat(v1): make FetchBlock and ReadData single-item operations#208
carbolymer wants to merge 1 commit into
utxorpc:feat/initialize-v1-versionfrom
carbolymer:sync-fetchblock-single-block

Conversation

@carbolymer

@carbolymer carbolymer commented Jul 3, 2026

Copy link
Copy Markdown
Contributor

Summary

  • Remove repeated from FetchBlockRequest.ref and FetchBlockResponse.block, making FetchBlock a single-block operation.
  • Remove repeated from ReadDataRequest.keys and ReadDataResponse.values (now key and value), making ReadData a single-datum operation.
  • Target the new v1 package; v1beta and v1alpha are untouched.
  • ReadUtxos keeps its batched shape on purpose, see below.

Motivation

These RPCs are per-item lookups, but the batched responses had no per-item error channel.
When one item could not be resolved, a server could only fail the whole call or silently omit the item, and the client could not tell omission from an error.
Existing implementations confirm the problem: Dolos fails the whole FetchBlock call on the first unresolvable ref, and dingo aborts both FetchBlock and ReadData on the first miss.
With single-item requests, the gRPC status code applies unambiguously to the one requested item.

Batching also bought nothing here, on either axis:

  • Performance: no implementation resolves these lists in a single storage operation. Dolos loops sequentially per block ref, dingo loops per point and per datum key, and cardano-node-api's FetchBlock handler is stubbed out. Concurrent single requests multiplexed over one HTTP/2 connection cost about the same as those loops.
  • Consistency: both methods read immutable, content-addressed data. A block fetched by hash and a datum fetched by its hash cannot change between requests, so a multi-item request carries no consistency guarantee that concurrent single requests lack.

This follows the same approach as #163, which made SubmitTx and EvalTx singular.

Why ReadUtxos is not following suit

ReadUtxos is the only one of the three that queries mutable ledger state, and its repeated keys field buys two things single-item requests cannot replicate:

  1. A real batch primitive. Cardano's local state query protocol resolves a set of TxIns in one ledger query (GetUTxOByTxIn), and implementations use it: cardano-node-api forwards the whole key list in a single N2C query, and dingo resolves all refs in one batched SQL query. Splitting into singles turns one lookup into N.
  2. Atomicity. Requests cannot pin a chain point, so a batched request is the only way to read N UTxOs against one consistent ledger view. With singles, ledger_tip only lets a client detect after the fact that its reads straddled a tip change.

The absent-vs-failed ambiguity described above affects ReadUtxos too, but it can be fixed without giving up batching: each response item could state explicitly whether the key was found (carrying the UTxO) or missing (echoing the key), so absence becomes an answer instead of a silence.
That is left out of scope for this PR.

Breaking change

This is a wire-incompatible change to the v1 package.
v1 is freshly initialised (565b990) and unreleased, so no published consumers are affected; v1beta and v1alpha are untouched.

@carbolymer carbolymer changed the title feat(sync): make FetchBlock accept a single block reference feat(v1beta): make FetchBlock, ReadUtxos and ReadData single-item operations Jul 20, 2026
@carbolymer
carbolymer force-pushed the sync-fetchblock-single-block branch 2 times, most recently from 16d52e3 to e3a8517 Compare July 20, 2026 15:40
@carbolymer
carbolymer force-pushed the sync-fetchblock-single-block branch 2 times, most recently from 6e0cec4 to 32bcb6a Compare August 20, 2026 13:21
@carbolymer carbolymer changed the title feat(v1beta): make FetchBlock, ReadUtxos and ReadData single-item operations feat(cardano): make FetchBlock, ReadUtxos and ReadData single-item operations Aug 20, 2026
@carbolymer
carbolymer changed the base branch from main to feat/initialize-v1-version August 20, 2026 13:22
@carbolymer carbolymer changed the title feat(cardano): make FetchBlock, ReadUtxos and ReadData single-item operations feat(v1): make FetchBlock and ReadData single-item operations Aug 20, 2026
@carbolymer
carbolymer force-pushed the sync-fetchblock-single-block branch from 32bcb6a to 22a60f3 Compare August 20, 2026 13:24
carbolymer added a commit to IntersectMBO/cardano-api that referenced this pull request Aug 20, 2026
The single-item FetchBlock variant moved to the upcoming utxorpc v1
(utxorpc/spec#208 was retargeted there), so v1beta keeps the repeated
request refs and response blocks. Regenerate the proto-lens Sync
modules and make the handler fetch every referenced block, failing the
whole call with NOT_FOUND naming the first missing ref's slot and
header hash, matching Dolos's all-or-nothing behaviour. Mark the
changelog fragment as breaking accordingly.
carbolymer added a commit to IntersectMBO/cardano-api that referenced this pull request Aug 27, 2026
The single-item FetchBlock variant moved to the upcoming utxorpc v1
(utxorpc/spec#208 was retargeted there), so v1beta keeps the repeated
request refs and response blocks. Regenerate the proto-lens Sync
modules and make the handler fetch every referenced block, failing the
whole call with NOT_FOUND naming the first missing ref's slot and
header hash, matching Dolos's all-or-nothing behaviour. Mark the
changelog fragment as breaking accordingly.
carbolymer added a commit to IntersectMBO/cardano-api that referenced this pull request Aug 27, 2026
The single-item FetchBlock variant moved to the upcoming utxorpc v1
(utxorpc/spec#208 was retargeted there), so v1beta keeps the repeated
request refs and response blocks. Regenerate the proto-lens Sync
modules and make the handler fetch every referenced block, failing the
whole call with NOT_FOUND naming the first missing ref's slot and
header hash, matching Dolos's all-or-nothing behaviour. Mark the
changelog fragment as breaking accordingly.
carbolymer added a commit to IntersectMBO/cardano-api that referenced this pull request Aug 27, 2026
The single-item FetchBlock variant moved to the upcoming utxorpc v1
(utxorpc/spec#208 was retargeted there), so v1beta keeps the repeated
request refs and response blocks. Regenerate the proto-lens Sync
modules and make the handler fetch every referenced block, failing the
whole call with NOT_FOUND naming the first missing ref's slot and
header hash, matching Dolos's all-or-nothing behaviour. Mark the
changelog fragment as breaking accordingly.
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants